package com.mti.zhpt.service.impl;

import com.mti.zhpt.base.BaseEntity;
import com.mti.zhpt.context.WebApplicationContext;
import com.mti.zhpt.enums.RelationNetTypeEnum;
import com.mti.zhpt.model.relationnet.*;
import com.mti.zhpt.service.BaseService;
import com.mti.zhpt.service.ControllerDispatchExecution;
import com.mti.zhpt.shared.Exception.BusinessException;
import com.mti.zhpt.vo.ModuleVO;
import com.mti.zhpt.vo.RelationNetDispatchVO;
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.StringUtils;

import java.lang.reflect.Field;
import java.util.*;
import java.util.stream.Collectors;

/**
 * @company 上海道枢信息科技-->
 * @anthor created by zhangmingxin
 * @date 2019/8/6
 * @change
 * @describe 联络网功能统一执行类
 **/
@Slf4j
@Component
@AllArgsConstructor
public class ControllerDispatchExecutionImpl implements ControllerDispatchExecution {
    private final WebApplicationContext context;

    /**
     * 分页获取数据列表
     * @param vo 分页数据
     * @return 列表
     */
    @Override
    public PageModel execution(RelationNetDispatchVO vo) {
        log.info("RelationNet.VO===>{}", vo.toString());
        BaseService<BaseEntity> service = getServiceByType(vo.getModuleType());
        if (service != null) {
            return service.list(vo.getPage(), vo.getSize(), vo.getOrgName(), vo.getPersonName(), vo.getPhone());
        }
        return null;
    }

    /**
     * 新增数据
     * @param t 数据集合
     */
    @Override
    @Transactional
    public void executionSave(Map t) {
        BaseService<BaseEntity> service = getServiceByType(t.getOrDefault("moduleType", "").toString());
        BaseEntity entity = transMapToEntity(t);
        Optional.ofNullable(entity).orElseThrow(()->new BusinessException("实体构造失败"));
        if (service != null)
            service.save(entity);
    }

    /**
     * 更新实体
     * @param t 实体集合数据
     */
    @Override
    @Transactional
    public void executionUpdate(Map t) {
        BaseService<BaseEntity> service = getServiceByType(t.getOrDefault("moduleType", "").toString());
        BaseEntity entity = transMapToEntity(t);
        Optional.ofNullable(entity).orElseThrow(()->new BusinessException("实体构造失败"));
        if (service != null)
            service.update(entity);
    }

    /**
     * 通过ID删除数据
     * @param id id
     * @param type type
     */
    @Override
    @Transactional
    public void executionDelete(String id, String type) {
        BaseService<BaseEntity> service = getServiceByType(type);
        if (service != null)
            service.deleteById(id);
    }

    /**
     * 通过ID获取实体
     * @param id id
     * @param moduleType type
     * @return entity
     */
    @Override
    public BaseEntity executionFindOneById(String id, String moduleType) {
        BaseService<BaseEntity> service = getServiceByType(moduleType);
        if (service != null)
            return service.getOneById(id);
        return null;
    }

    @Override
    public List getModuleList() {
        return Arrays.stream(RelationNetTypeEnum.values()).map(item->new ModuleVO(RelationNetTypeEnum.getNameByCode(item.name()),item.name())).collect(Collectors.toList());
    }

    @Override
    public List<Map<String,String>> executeSecondModuleList(String type, String moduleType) {
        BaseService<BaseEntity> service = getServiceByType(moduleType);
        if (service != null){
            PageModel<List<String>> list = service.listByGroupBy(0,1000,moduleType);
            if(list!=null && list.getRecord()!=null){
                return list.getRecord().stream().map(item->
                {
                    Map<String,String> m = new HashMap<>();
                    m.put("name",item);
                    return m;
                }).collect(Collectors.toList());
            }
        }
        return null;
    }

    /**
     * 根据类型获取bean
     *
     * @param type type
     * @return bean
     */
    private BaseService<BaseEntity> getServiceByType(String type) {
        return (BaseService<BaseEntity>) context.getBeanByName(type);
    }

    /**
     * 通过type得到实体
     * @param map map
     * @return entity
     */
    private BaseEntity transMapToEntity(Map<String, Object> map) {
        if (map.isEmpty())
            return null;
        try {
            String code = map.getOrDefault("moduleType", "").toString();
            BaseEntity baseEntity = (BaseEntity) Class.forName("com.mti.zhpt.model.relationnet."+code).newInstance();
            fullValToEntity(baseEntity,map);
            return baseEntity;
        } catch (Exception e) {
            e.printStackTrace();
            log.error("error==>{}", e.getMessage());
            return null;
        }
    }

    /**
     * 利用反射填充实体的值
     * @param entity 实体
     * @param map map
     * @return 填充值后的实体
     */
    private void fullValToEntity(BaseEntity entity,Map<String,Object> map) throws IllegalAccessException {
        List<Field> fields = new ArrayList<>();
        fields.addAll(Arrays.asList(entity.getClass().getDeclaredFields()));
        fields.addAll(Arrays.asList(entity.getClass().getFields()));
        for(Field f:fields){
            if(map.containsKey(f.getName())){
                f.setAccessible(true);
                f.set(entity,map.get(f.getName()));
            }
        }
    }
}
